#pragma once

#include <vector>
#include <memory>
#include <functional>
#include <QString>
#include <QStringLiteral>
#include <QVector>
#include <QDebug>
#include <QThreadPool>
#include <QRunnable>

#ifndef PRAGMA_DISABLE_DEPRECATION_WARNINGS
#define PRAGMA_DISABLE_DEPRECATION_WARNINGS \
			__pragma (warning(push)) \
			__pragma (warning(disable: 4995)) /* 'function': name was marked as #pragma deprecated */ \
			__pragma (warning(disable: 4996)) /* The compiler encountered a deprecated declaration. */

#ifndef PRAGMA_ENABLE_DEPRECATION_WARNINGS
#define PRAGMA_ENABLE_DEPRECATION_WARNINGS \
			__pragma (warning(pop))
#endif // PRAGMA_ENABLE_DEPRECATION_WARNINGS
#include <windows.h>
#include <winnt.h>
#endif // PRAGMA_DISABLE_DEPRECATION_WARNINGS


extern bool GIsRequestingExit;
extern bool GIsEditor;

FORCEINLINE bool IsEngineExitRequested()
{
	PRAGMA_DISABLE_DEPRECATION_WARNINGS
		return GIsRequestingExit;
	PRAGMA_ENABLE_DEPRECATION_WARNINGS
}

/*----------------------------------------------------------------------------
    VGameEngine渲染命令系统
----------------------------------------------------------------------------*/

// 前向声明
class VGameEngine;

// 渲染命令基类
class VGRenderCommand
{
public:
    virtual ~VGRenderCommand() = default;
    virtual void Execute() = 0;
};

// 渲染命令管理器 - 支持Qt+UE4风格
class VGRenderCommandQueue
{
public:
    static VGRenderCommandQueue& Get();
    
    void EnqueueCommand(VGRenderCommand* command);
    void ExecuteCommands();
    void ClearCommands();
    
    // 基于UE4+Qt的模板方法 - 使用线程池
    template<typename CommandTag>
    void EnqueueUniqueRenderCommand(std::function<void()> command)
    {
        qDebug() << "Enqueuing render command:" << CommandTag::GetName();
        m_LambdaCommands.append(command);
    }
    
    // 使用线程池执行命令
    void ExecuteCommandsInThreadPool();

private:
    std::vector<VGRenderCommand*> m_Commands;
    QVector<std::function<void()>> m_LambdaCommands; // Qt容器存储lambda
    static VGRenderCommandQueue* s_Instance;
};

// 基于UE4+Qt的宏辅助工具
#define VG_JOIN(TokenA, TokenB) VG_PRIVATE_JOIN(TokenA, TokenB)
#define VG_PRIVATE_JOIN(TokenA, TokenB) TokenA##TokenB
#define VG_PREPROCESSOR_JOIN(TokenA, TokenB) VG_JOIN(TokenA, TokenB)
#define VG_UNIQUE_NAME(prefix) VG_PREPROCESSOR_JOIN(prefix, __LINE__)

// Qt风格的渲染命令标签模板
template <typename QSTR>
struct VGRenderCommandTag
{
    static QString GetName() { return QSTR::QStr(); }
    static const char* GetCName() { return QSTR::CStr(); }
};

// 基于Qt+UE4的渲染命令标签声明
#define DECLARE_VG_RENDER_COMMAND_TAG(Type, Name) \
    struct VG_PREPROCESSOR_JOIN(QSTR_, VG_PREPROCESSOR_JOIN(Name, __LINE__)) \
    { \
        static const char* CStr() { return #Name; } \
        static QString QStr() { return QStringLiteral(#Name); } \
    }; \
    using Type = VGRenderCommandTag<VG_PREPROCESSOR_JOIN(QSTR_, VG_PREPROCESSOR_JOIN(Name, __LINE__))>;

// ENQUEUE_RENDER_COMMAND宏定义 - 基于UE4+Qt实现
#define ENQUEUE_RENDER_COMMAND(Type) \
    DECLARE_VG_RENDER_COMMAND_TAG(VG_PREPROCESSOR_JOIN(VGRenderCommandTag_, VG_PREPROCESSOR_JOIN(Type, __LINE__)), Type) \
    VGRenderCommandQueue::Get().EnqueueUniqueRenderCommand<VG_PREPROCESSOR_JOIN(VGRenderCommandTag_, VG_PREPROCESSOR_JOIN(Type, __LINE__))>


qint32 EditorInit(class IVGEngineLoop& EngineLoop);


extern class VLevelEditor* LevelEditor;
